home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCSid = "$Id: command.c,v 1.92 1995/12/14 21:08:54 drd Exp $";
- #endif
-
-
- /* GNUPLOT - command.c */
- /*
- * Copyright (C) 1986 - 1993 Thomas Williams, Colin Kelley
- *
- * Permission to use, copy, and distribute this software and its documentation
- * for any purpose with or without fee is hereby granted, provided that the
- * above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to distribute
- * the modified code. Modifications are to be distributed as patches to
- * released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- *
- * AUTHORS
- *
- * Original Software: Thomas Williams, Colin Kelley.
- *
- * Gnuplot 2.0 additions: Russell Lang, Dave Kotz, John Campbell.
- *
- * Gnuplot 3.0 additions: Gershon Elber and many others.
- *
- * Nonlinear Least squares fit:
- * Carsten Grammes
- *
- * Changes:
- *
- * Feb 5, 1992 Jack Veenstra (veenstra@cs.rochester.edu) Added support to
- * filter data values read from a file through a user-defined function before
- * plotting. The keyword "thru" was added to the "plot" command. Example
- * syntax: f(x) = x / 100 plot "test.data" thru f(x) This example divides all
- * the y values by 100 before plotting. The filter function processes the
- * data before any log-scaling occurs. This capability should be generalized
- * to filter x values as well and a similar feature should be added to the
- * "splot" command.
- *
- * 19 September 1992 Lawrence Crowl (crowl@cs.orst.edu)
- * Added user-specified bases for log scaling.
- *
- * There is a mailing list for gnuplot users. Note, however, that the
- * newsgroup
- * comp.graphics.gnuplot
- * is identical to the mailing list (they
- * both carry the same set of messages). We prefer that you read the
- * messages through that newsgroup, to subscribing to the mailing list.
- * (If you can read that newsgroup, and are already on the mailing list,
- * please send a message info-gnuplot-request@dartmouth.edu, asking to be
- * removed from the mailing list.)
- *
- * The address for mailing to list members is
- * info-gnuplot@dartmouth.edu
- * and for mailing administrative requests is
- * info-gnuplot-request@dartmouth.edu
- * The mailing list for bug reports is
- * bug-gnuplot@dartmouth.edu
- * Send bug reports regarding the fit to
- * cagr@rz.uni-sb.de
- * The list of those interested in beta-test versions is
- * info-gnuplot-beta@dartmouth.edu
- */
-
- #include <math.h>
- #include <ctype.h>
- #include <assert.h>
-
- #ifdef AMIGA_AC_5
- void sleep(); /* defined later */
- #endif
-
- #ifdef VMS
- #include <signal.h> /* for sleep() */
- #endif
-
- #if defined(MSDOS) || defined(DOS386)
- #ifdef DJGPP
- #include <dos.h>
- #else
- #include <process.h>
- #endif
-
- #ifdef __ZTC__
- #define P_WAIT 0
- #else
-
- #ifdef __TURBOC__
- #ifndef _Windows
- #include <dos.h> /* sleep() */
- #include <conio.h>
- #include <dir.h> /* setdisk() */
- extern unsigned _stklen = 16394;/* increase stack size */
- extern char HelpFile[80] ; /* patch for do_help - DJL */
- #endif
-
- #else /* must be MSC */
- #if !defined(__EMX__) && !defined(DJGPP)
- #ifdef __MSC__
- #include <direct.h> /* for _chdrive() */
- #endif
- void sleep(); /* defined later */
- #endif /* !__EMX__ && !DJGPP */
- #endif /* TURBOC */
- #endif /* ZTC */
-
- #endif /* MSDOS */
-
- #ifdef AMIGA_SC_6_1
- #include <proto/dos.h>
- void sleep();
- #endif /* AMIGA_SC_6_1 */
-
- #include "plot.h"
- #include "setshow.h"
- #include "fit.h"
- #include "binary.h"
- #ifndef _Windows
- #include "help.h"
- #else
- #define MAXSTR 255
- #endif
-
- #if defined(ATARI) || defined(MTOS)
- #ifdef __PUREC__
- #include <ext.h>
- #include <tos.h>
- #include <aes.h>
- #include <float.h> /* get FLT_MAX */
- #else
- #include <osbind.h>
- #include <aesbind.h>
- #include <support.h>
- #endif /* __PUREC__ */
- #endif /* ATARI || MTOS */
-
- #ifndef STDOUT
- #define STDOUT 1
- #endif
-
- #ifndef HELPFILE
- #if defined( MSDOS ) || defined( OS2 ) || defined(DOS386)
- #define HELPFILE "gnuplot.gih"
- #else
- #ifdef AMIGA_SC_6_1
- #define HELPFILE "S:gnuplot.gih"
- #else
- #define HELPFILE "docs/gnuplot.gih" /* changed by makefile */
- #endif /* AMIGA_SC_6_1 */
- #endif
- #endif /* HELPFILE */
-
- #ifdef _Windows
- #include <windows.h>
- #ifdef __MSC__
- #include <malloc.h>
- #else
- #include <alloc.h>
- #include <dir.h> /* setdisk() */
- #endif
- #include "win/wgnuplib.h"
- void sleep();
- extern TW textwin;
- extern LPSTR winhelpname;
- extern void screen_dump(void); /* in term/win.trm */
- extern int Pause(LPSTR mess); /* in winmain.c */
- #endif
-
- #define inrange(z,min,max) ((min<max) ? ((z>=min)&&(z<=max)) : ((z>=max)&&(z<=min)) )
-
- /* purec_sscanf is now in datafile.c */
- #ifdef __PUREC__
- # define sscanf purec_sscanf
- #endif
-
- #ifdef OS2
- /* emx has getcwd, chdir that can handle drive names */
- #define getcwd _getcwd2
- #define chdir _chdir2
- #endif /* OS2 */
-
- #if (defined(unix) || defined(OSK))
- #ifdef GETCWD
- extern char *getcwd(); /* some Unix's use getcwd */
- #else
- extern char *getwd(); /* most Unix's use getwd */
- #endif
- #else
- #ifdef DJGPP
- extern char *getwd(); /* DJGPP acts like Unix here */
- #else
- extern char *getcwd(); /* Turbo C, MSC, EMX, OS2 and VMS use getcwd */
- #endif
- #endif
-
- #ifdef vms
- int vms_vkid; /* Virtual keyboard id */
- #endif
-
-
- /* static prototypes */
-
- static void replotrequest __P((void));
- static int command __P((void));
- static int read_line __P((char *prompt));
- static void do_shell __P((void));
- static void do_help __P((void));
- static void do_system __P((void));
- static int changedir __P((char *path));
- static void getpath __P((char *string));
-
- #if defined(AMIGA_SC_6_1)
- void sleep __P((unsigned int delay));
- #endif
-
- extern int chdir();
-
- /* input data, parsing variables */
- #ifdef AMIGA_SC_6_1
- __far int num_tokens, c_token;
- #else
- int num_tokens, c_token;
- #endif
-
- extern TBOOLEAN do_load_arg_substitution;
- struct lexical_unit *token=NULL;
- int token_table_size=0;
-
- char *input_line=NULL;
- int input_line_len=0;
- int inline_num = 0; /* input line number */
-
- /* things shared by plot2d.c and plot3d.c are here, for historical reasons */
-
- double min_array[AXIS_ARRAY_SIZE], max_array[AXIS_ARRAY_SIZE];
- int auto_array[AXIS_ARRAY_SIZE];
- TBOOLEAN log_array[AXIS_ARRAY_SIZE];
- double base_array[AXIS_ARRAY_SIZE];
- double log_base_array[AXIS_ARRAY_SIZE];
- struct udft_entry *dummy_func=NULL; /* NULL means no dummy vars active */
-
- char c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN + 1]; /* current dummy vars */
-
-
- /* support for replot command */
- char *replot_line=NULL;
- int plot_token; /* start of 'plot' command */
-
- /* If last plot was a 3d one. */
- TBOOLEAN is_3d_plot = FALSE;
-
-
- extern TBOOLEAN term_graphics, term_suspended;
-
- #ifndef min
- #define min(a,b) ((a)>(b) ? (b) : (a))
- #endif
- #define Inc_c_token if (++c_token >= num_tokens) \
- int_error ("Syntax error", c_token);
-
-
- /* support for dynamic size of input line */
-
- void extend_input_line()
- {
- if(input_line_len==0) {
- /* first time */
- input_line=alloc(MAX_LINE_LEN, "input_line");
- input_line_len=MAX_LINE_LEN;
- input_line[0]='\0';
- } else {
- input_line=ralloc(input_line, input_line_len+MAX_LINE_LEN, "extend input line");
- input_line_len+=MAX_LINE_LEN;
- #ifdef DEBUG_STR
- fprintf(stderr, "extending input line to %d chars\n", input_line_len);
- #endif
- }
- }
-
- void extend_token_table()
- {
- if(token_table_size==0) {
- /* first time */
- token=(struct lexical_unit *)alloc(MAX_TOKENS*sizeof(struct lexical_unit), "token table");
- token_table_size=MAX_TOKENS;
- } else {
- token=ralloc(token, (token_table_size+MAX_TOKENS)*sizeof(struct lexical_unit), "extend token table");
- token_table_size+=MAX_TOKENS;
- #ifdef DEBUG_STR
- fprintf(stderr, "extending token table to %d elements\n", token_table_size);
- #endif
- }
- }
-
- void init_memory()
- {
- extend_input_line();
- extend_token_table();
- replot_line=alloc(1, "string");
- *replot_line='\0';
- }
-
- int com_line()
- {
- if (multiplot) {
- if (term_graphics && !term_suspended && interactive) {
- /* make sure that it is safe to issue an interactive prompt */
- if ( (term->flags & TERM_CAN_MULTIPLOT) ||
- ( (outfile!=stdout) && !(term->flags & TERM_CANNOT_MULTIPLOT) )
- )
- {
- /* it's okay to use multiplot here */
- if (term->suspend)
- (*term->suspend)();
- term_suspended = TRUE;
- }
- else
- /* we cant do interactive multiplot here */
- graph_error("Cant do interactive multiplot with this driver");
- } /* interactive */
-
- if (read_line("multiplot> "))
- return(1);
- } else {
- if (read_line(PROMPT))
- return(1);
- }
-
- /* So we can flag any new output: if false at time of error, */
- /* we reprint the command line before printing caret. */
- /* TRUE for interactive terminals, since the command line is typed. */
- /* FALSE for non-terminal stdin, so command line is printed anyway. */
- /* (DFK 11/89) */
- screen_ok = interactive;
-
- if (do_line())
- return(1);
- else
- return(0);
- }
-
- #ifdef OS2
- int set_input_line( char *line, int nchar )
- {
- strncpy( input_line, line, nchar ) ;
- input_line[nchar]='\0';
- }
- #endif
-
- int do_line()
- { /* also used in load_file */
- if (is_system(input_line[0])) {
- do_system();
- (void) fputs("!\n", stderr);
- return(0);
- }
- num_tokens = scanner(input_line);
- c_token = 0;
- while (c_token < num_tokens) {
- if (command())
- return(1);
- if (c_token < num_tokens) /* something after command */
- if (equals(c_token, ";"))
- c_token++;
- else
- int_error("';' expected", c_token);
- }
- return(0);
- }
-
-
- void define()
- {
- register int start_token;/* the 1st token in the function definition */
- register struct udvt_entry *udv;
- register struct udft_entry *udf;
-
- if (equals(c_token + 1, "(")) {
- /* function ! */
- int dummy_num = 0;
- char save_dummy[MAX_NUM_VAR][MAX_ID_LEN+1];
- memcpy(save_dummy, c_dummy_var, sizeof(save_dummy));
- start_token = c_token;
- do {
- c_token += 2; /* skip to the next dummy */
- copy_str(c_dummy_var[dummy_num++], c_token, MAX_ID_LEN);
- } while (equals(c_token + 1, ",") && (dummy_num < MAX_NUM_VAR));
- if (equals(c_token + 1, ","))
- int_error("function contains too many parameters", c_token + 2);
- c_token += 3; /* skip (, dummy, ) and = */
- if (END_OF_COMMAND)
- int_error("function definition expected", c_token);
- udf = dummy_func = add_udf(start_token);
- if (udf->at) /* already a dynamic a.t. there */
- free((char *) udf->at); /* so free it first */
- if ((udf->at = perm_at()) == (struct at_type *) NULL)
- int_error("not enough memory for function", start_token);
- memcpy(c_dummy_var, save_dummy, sizeof(save_dummy));
- m_capture(&(udf->definition), start_token, c_token - 1);
- dummy_func=NULL; /* dont let anyone else use our workspace */
- } else {
- /* variable ! */
- start_token = c_token;
- c_token += 2;
- udv = add_udv(start_token);
- (void) const_express(&(udv->udv_value));
- udv->udv_undef = FALSE;
- }
- }
-
-
- static int command()
- {
- FILE *fp, *lf_top();
- int i;
- char sv_file[MAX_LINE_LEN + 1];
- /* string holding name of save or load file */
-
- for (i = 0; i < MAX_NUM_VAR; i++)
- c_dummy_var[i][0] = '\0'; /* no dummy variables */
-
- if (is_definition(c_token))
- define();
- else if (almost_equals(c_token, "h$elp") || equals(c_token, "?")) {
- c_token++;
- do_help();
- } else if (almost_equals(c_token, "test")) {
- c_token++;
- test_term();
- } else if (almost_equals(c_token, "scr$eendump")) {
- c_token++;
- #ifdef _Windows
- screen_dump();
- #else
- fputs("screendump not implemented\n",stderr);
- #endif
- } else if (almost_equals(c_token, "pa$use")) {
- struct value a;
- int stime, text = 0;
- char buf[MAX_LINE_LEN + 1];
-
- c_token++;
- stime = (int) real(const_express(&a));
- buf[0]='\0';
- if (!(END_OF_COMMAND)) {
- if (!isstring(c_token))
- int_error("expecting string", c_token);
- else {
- quote_str(buf, c_token, MAX_LINE_LEN);
- #ifdef _Windows
- if (stime>=0)
- #endif
- #ifdef OS2
- if( strcmp(term->name, "pm" )!=0 || stime >=0 )
- #endif
- #ifdef MTOS
- if( strcmp(term->name, "mtos" )!=0 || stime >=0 )
- #endif
- (void) fprintf(stderr, "%s", buf);
- text = 1;
- }
- }
- if (stime < 0)
- #ifdef _Windows
- {
- if (!Pause(buf))
- longjmp(env, TRUE); /* bail out to command line */
- }
- #else
- #ifdef OS2
- if( strcmp(term->name, "pm" )==0 && stime < 0 )
- {
- int rc ;
- if( (rc=PM_pause( buf ))==0 ) longjmp(env,TRUE) ;
- else if( rc==2 ) {
- (void) fprintf(stderr, "%s", buf);
- text = 1;
- (void) fgets(buf, MAX_LINE_LEN, stdin);
- }
-
- }
- #else
- #ifdef MTOS
- {
- if( strcmp(term->name, "mtos" )==0) {
- int MTOS_pause(char *buf);
- int rc;
- if ((rc = MTOS_pause(buf)) == 0)
- longjmp(env,TRUE);
- else if (rc == 2) {
- (void) fprintf(stderr, "%s", buf);
- text = 1;
- (void) fgets(buf, MAX_LINE_LEN, stdin);
- }
- }
- else if( strcmp(term->name, "atari" )==0) {
- char *readline(char *);
- char *line=readline("");
- if(line) free(line);
- }
- else
- (void) fgets(buf, MAX_LINE_LEN, stdin);
- }
- #else
- #ifdef ATARI
- {
- else if( strcmp(term->name, "atari" )==0) {
- char *readline(char *);
- char *line=readline("");
- if(line) free(line);
- }
- else
- (void) fgets(buf, MAX_LINE_LEN, stdin);
- }
- #else /* ATARI */
- (void) fgets(buf, MAX_LINE_LEN, stdin);
- /* Hold until CR hit. */
- #endif /* MTOS */
- #endif /* ATARI */
- #endif /*OS2*/
- #endif
- #ifdef __ZTC__
- if (stime > 0)
- usleep((unsigned long) stime);
- #else
- if (stime > 0)
- sleep((unsigned int) stime);
- #endif
- if (text != 0 && stime >= 0)
- (void) fprintf(stderr, "\n");
- c_token++;
- screen_ok = FALSE;
- }
- else if (almost_equals(c_token, "pr$int")) {
- struct value a;
-
- c_token++;
- (void) const_express(&a);
- (void) putc('\t', stderr);
- disp_value(stderr, &a);
- (void) putc('\n', stderr);
- screen_ok = FALSE;
- } else if (almost_equals(c_token,"fit")) {
- ++c_token;
- do_fit();
- }
- else if (almost_equals(c_token,"up$date")) {
- char tmps[80];
- if ( !isstring(++c_token) )
- int_error ("Parameter filename expected", c_token);
- quote_str (tmps, c_token++, 80);
- update (tmps);
- }
- else if (almost_equals(c_token, "p$lot")) {
- plot_token = c_token++;
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
- #endif
- plotrequest();
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
- #endif
- } else if (almost_equals(c_token, "sp$lot")) {
- plot_token = c_token++;
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
- #endif
- plot3drequest();
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
- #endif
- } else if (almost_equals(c_token, "rep$lot")) {
- if (replot_line[0] == '\0')
- int_error("no previous plot", c_token);
- c_token++;
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_WAIT));
- #endif
- replotrequest();
- #ifdef _Windows
- SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
- #endif
- } else if (almost_equals(c_token, "se$t"))
- set_command();
- else if (almost_equals(c_token, "res$et"))
- reset_command();
- else if (almost_equals(c_token, "sh$ow"))
- show_command();
- else if (almost_equals(c_token, "cl$ear")) {
- if (!term_init) {
- (*term->init) ();
- term_init = TRUE;
- }
- if (term_graphics) {
- if (multiplot && term_suspended && term->resume)
- {
- (*term->resume)();
- term_suspended = FALSE;
- }
- (*term->text)();
- }
- (*term->graphics) ();
- (*term->text) ();
- (void) fflush(outfile);
- screen_ok = FALSE;
- c_token++;
- } else if (almost_equals(c_token, "she$ll")) {
- do_shell();
- screen_ok = FALSE;
- c_token++;
- } else if (almost_equals(c_token, "sa$ve")) {
- if (almost_equals(++c_token, "f$unctions")) {
- if (!isstring(++c_token))
- int_error("expecting filename", c_token);
- else {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- save_functions(fopen(sv_file, "w"));
- }
- } else if (almost_equals(c_token, "v$ariables")) {
- if (!isstring(++c_token))
- int_error("expecting filename", c_token);
- else {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- save_variables(fopen(sv_file, "w"));
- }
- } else if (almost_equals(c_token, "s$et")) {
- if (!isstring(++c_token))
- int_error("expecting filename", c_token);
- else {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- save_set(fopen(sv_file, "w"));
- }
- } else if (isstring(c_token)) {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- save_all(fopen(sv_file, "w"));
- } else {
- int_error(
- "filename or keyword 'functions', 'variables', or 'set' expected",
- c_token);
- }
- c_token++;
- } else if (almost_equals(c_token, "l$oad")) {
- if (!isstring(++c_token))
- int_error("expecting filename", c_token);
- else {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- load_file(fp=fopen(sv_file, "r"), sv_file, FALSE);
- /* input_line[] and token[] now destroyed! */
- c_token = num_tokens = 0;
- }
- } else if (almost_equals(c_token,"ca$ll")) {
- if (!isstring(++c_token))
- int_error("expecting filename",c_token);
- else {
- quote_str(sv_file,c_token, MAX_LINE_LEN);
- load_file(fopen(sv_file,"r"), sv_file, TRUE); /* Argument list follows filename */
- /* input_line[] and token[] now destroyed! */
- c_token = num_tokens = 0;
- }
- } else if (almost_equals(c_token,"if")) {
- float exprval;
- struct value t;
- if (!equals(++c_token, "(")) /* no expression */
- int_error("expecting (expression)", c_token);
- exprval = real(const_express(&t));
- if (exprval != 0.0) {
- /* fake the condition of a ';' between commands */
- int eolpos = token[num_tokens-1].start_index+token[num_tokens-1].length;
- --c_token;
- token[c_token].length = 1;
- token[c_token].start_index = eolpos+2;
- input_line[eolpos+2] = ';';
- input_line[eolpos+3] = '\0';
- } else
- c_token = num_tokens = 0;
- } else if (almost_equals(c_token,"rer$ead")) {
- fp = lf_top();
- if (fp != (FILE *)NULL) rewind(fp);
- c_token++;
- } else if (almost_equals(c_token, "cd")) {
- if (!isstring(++c_token))
- int_error("expecting directory name", c_token);
- else {
- quote_str(sv_file, c_token, MAX_LINE_LEN);
- if (changedir(sv_file)) {
- int_error("Can't change to this directory", c_token);
- }
- c_token++;
- }
- } else if (almost_equals(c_token, "pwd")) {
- getpath(sv_file);
- fprintf(stderr, "%s\n", sv_file);
- c_token++;
- } else if (almost_equals(c_token, "ex$it") ||
- almost_equals(c_token, "q$uit")) {
- /* graphics will be tidied up in main */
- return(1);
- } else if (!equals(c_token, ";")) { /* null statement */
- #ifdef OS2
- {
- if( token[c_token].is_token ) {
- char cmd[80] ;
- strncpy(cmd,input_line+token[c_token].start_index,token[c_token].length);
- cmd[token[c_token].length] = '\0' ;
- ++c_token;
- if(ExecuteMacro(cmd)==0) return(0);
- }
- }
- #endif
- int_error("invalid command", c_token);
- }
- return(0);
- }
-
-
- void done(status)
- int status;
- {
- if (term && term_init) {
- (*term->reset) ();
- term_init=0; /* x11 doesn't like to be reset twice */
- }
- #ifdef vms
- vms_reset();
- #endif
- exit(status);
- }
-
- static int changedir(path)
- char *path;
- {
- #if defined(MSDOS) || defined(_Windows) || defined(ATARI) || defined(DOS386)
- #if defined(__ZTC__)
- unsigned dummy; /* it's a parameter needed for dos_setdrive */
- #endif
-
- /* first deal with drive letter */
-
- if (isalpha(path[0]) && (path[1]==':')) {
- int driveno=toupper(path[0])-'A'; /* 0=A, 1=B, ... */
- #if defined(ATARI)
- (void)Dsetdrv(driveno);
- #endif
-
- #if defined(__ZTC__)
- (void)dos_setdrive(driveno + 1, &dummy);
- #endif
-
- #if defined(MSDOS) && defined(__EMX__)
- (void)_chdrive(driveno + 1);
- #endif
- #if defined(__MSC__)
- (void)_chdrive(driveno+1);
- #endif
- #if (defined(MSDOS) || defined(_Windows)) && defined(__TURBOC__)
- (void) setdisk(driveno);
- #endif
- #ifdef DJGPP
- { union REGS r;
- r.h.ah = 0x0e;
- r.x.dx = driveno;
- intdos(&r, &r);
- }
- #endif
- path += 2; /* move past drive letter */
- }
- /* then change to actual directory */
- if (*path)
- if (chdir(path))
- return 1;
-
- return 0; /* should report error with setdrive also */
- #else /* MSDOS, ATARI etc. */
- return chdir(path);
- #endif /* MSDOS, ATARI etc. */
- }
-
- static void getpath(string)
- char *string;
- {
- #if 0 /* def DJGPP */
- { union REGS r;
- r.h.ah = 0x19;
- intdos(&r, &r);
- sprintf(string, "%c:", r.h.al + 'a');
- string+=2;
- }
- #endif
- #if (defined(unix) || defined(OSK))
- #ifdef GETCWD
- (void) getcwd(string, MAX_LINE_LEN); /* some Unix's use getcwd */
- #else
- (void) getwd(string); /* most Unix's use getwd */
- #endif
- #else /* unix */
- #ifdef __EMX__
- (void) _getcwd2(string, MAX_ID_LEN);
- #else
- /* Turbo C and VMS have getcwd() */
- (void) getcwd(string, MAX_LINE_LEN);
- #endif
- #endif /* unix */
- }
-
- static void replotrequest()
- {
- int newlen;
- int last_token;
-
- if (equals(c_token, "["))
- int_error("cannot set range with replot", c_token);
- if (!END_OF_COMMAND) {
- last_token=num_tokens-1;
- /* length = length of old part + length of new part + ',' + \0 */
- newlen=strlen(replot_line)+token[last_token].start_index+token[last_token].length-token[c_token].start_index+2;
- replot_line=ralloc(replot_line, (unsigned long)newlen, "extend replot line");
- strcat(replot_line, ",");
- capture(replot_line+strlen(replot_line), c_token, num_tokens - 1, newlen-strlen(replot_line));
-
- #ifdef DEBUG_STR
- fprintf(stderr, "new replot_line length %d\n", strlen(replot_line));
- #endif
- }
-
- while(strlen(replot_line+1)>input_line_len)
- extend_input_line();
-
- (void) strcpy(input_line, replot_line);
- screen_ok = FALSE;
- num_tokens = scanner(input_line);
- c_token = 1; /* skip the 'plot' part */
- if(is_3d_plot)
- plot3drequest();
- else plotrequest();
- }
-
- #ifdef AMIGA_SC_6_1
- void
- sleep(delay)
- unsigned int delay;
- {
- Delay(50 * delay);
- }
- #endif
-
- #ifdef AMIGA_AC_5
- void
- sleep(delay)
- unsigned int delay;
- {
- unsigned long time_is_up;
- time_is_up = time(NULL) + (unsigned long) delay;
- while (time(NULL) < time_is_up)
- /* wait */ ;
- }
- #endif
-
- #if defined(MSDOS) || defined(_Windows) || defined(DOS386)
- #if (!defined(__TURBOC__) && !defined(__EMX__) && !defined(DJGPP)) || defined(_Windows) /* Turbo C already has sleep() */
- #ifndef __ZTC__ /* ZTC already has usleep() */
- /* kludge to provide sleep() for msc 5.1 */
- void
- sleep(delay)
- unsigned int delay;
- {
- unsigned long time_is_up;
- time_is_up = time(NULL) + (unsigned long) delay;
- while (time(NULL) < time_is_up)
- /* wait */ ;
- }
- #endif /* not ZTC */
- #endif /* (!TURBOC && !__EMX__ && !DJGPP) or _Windows */
- #endif /* MSDOS || _Windows*/
-
-
- /* Support for input, shell, and help for various systems */
-
- #ifdef vms
-
- #include <descrip.h>
- #include <rmsdef.h>
- #include <smgdef.h>
- #include <smgmsg.h>
-
- extern lib$get_input(), lib$put_output();
- extern smg$read_composed_line();
- extern sys$putmsg();
- extern lbr$output_help();
- extern lib$spawn();
-
- int vms_len;
-
- unsigned int status[2] =
- {1, 0};
-
- static char Help[MAX_LINE_LEN + 1] = "gnuplot";
-
- $DESCRIPTOR(prompt_desc, PROMPT);
- /* temporary fix until change to variable length */
- struct dsc$descriptor_s line_desc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL };
-
- $DESCRIPTOR(help_desc, Help);
- $DESCRIPTOR(helpfile_desc, "GNUPLOT$HELP");
-
- /* please note that the vms version of read_line doesn't support variable line
- length (yet) */
-
- static int read_line(prompt)
- char *prompt;
- {
- int more, start = 0;
- char expand_prompt[40];
-
- prompt_desc.dsc$w_length = strlen(prompt);
- prompt_desc.dsc$a_pointer = prompt;
- (void) strcpy(expand_prompt, "_");
- (void) strncat(expand_prompt, prompt, 38);
- do {
- line_desc.dsc$w_length = MAX_LINE_LEN - start;
- line_desc.dsc$a_pointer = &input_line[start];
- switch (status[1] = smg$read_composed_line(&vms_vkid, 0, &line_desc, &prompt_desc, &vms_len)) {
- case SMG$_EOF:
- done(IO_SUCCESS); /* ^Z isn't really an error */
- break;
- case RMS$_TNS: /* didn't press return in time */
- vms_len--; /* skip the last character */
- break; /* and parse anyway */
- case RMS$_BES: /* Bad Escape Sequence */
- case RMS$_PES: /* Partial Escape Sequence */
- sys$putmsg(status);
- vms_len = 0; /* ignore the line */
- break;
- case SS$_NORMAL:
- break; /* everything's fine */
- default:
- done(status[1]); /* give the error message */
- }
- start += vms_len;
- input_line[start] = '\0';
- inline_num++;
- if (input_line[start - 1] == '\\') {
- /* Allow for a continuation line. */
- prompt_desc.dsc$w_length = strlen(expand_prompt);
- prompt_desc.dsc$a_pointer = expand_prompt;
- more = 1;
- --start;
- } else {
- line_desc.dsc$w_length = strlen(input_line);
- line_desc.dsc$a_pointer = input_line;
- more = 0;
- }
- } while (more);
- return 0;
- }
-
-
- static void do_help()
- {
- int first=c_token;
- while (!END_OF_COMMAND)
- ++c_token;
-
- strcpy(Help, "GNUPLOT ");
- capture(Help+8, first, c_token-1, sizeof(Help)-9);
- help_desc.dsc$w_length = strlen(Help);
- if ((vaxc$errno = lbr$output_help(lib$put_output, 0, &help_desc,
- &helpfile_desc, 0, lib$get_input)) != SS$_NORMAL)
- os_error("can't open GNUPLOT$HELP", NO_CARET);
- }
-
-
- static void do_shell()
- {
- if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
- os_error("spawn error", NO_CARET);
- }
- }
-
-
- static void do_system()
- {
- input_line[0] = ' '; /* an embarrassment, but... */
-
- if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
- os_error("spawn error", NO_CARET);
-
- (void) putc('\n', stderr);
- }
-
- #else /* vms */
-
- #ifdef _Windows
- static void do_help()
- {
- if (END_OF_COMMAND)
- WinHelp(textwin.hWndParent,(LPSTR)winhelpname,HELP_INDEX,(DWORD)NULL);
- else {
- char buf[128];
- int start = c_token++;
- while (!(END_OF_COMMAND))
- c_token++;
- capture(buf, start, c_token-1, 128);
- WinHelp(textwin.hWndParent,(LPSTR)winhelpname,HELP_PARTIALKEY,(DWORD)buf);
- }
- }
- #else
-
- /*
- * do_help: (not VMS, although it would work) Give help to the user. It
- * parses the command line into helpbuf and supplies help for that string.
- * Then, if there are subtopics available for that key, it prompts the user
- * with this string. If more input is given, do_help is called recursively,
- * with the argument the index of null character in the string. Thus a more
- * specific help can be supplied. This can be done repeatedly. If null input
- * is given, the function returns, effecting a backward climb up the tree.
- * David Kotz (David.Kotz@Dartmouth.edu) 10/89
- */
-
- static void do_help()
- {
- static char *helpbuf = NULL;
- static char *prompt = NULL;
- int base; /* index of first char AFTER help string */
- int len; /* length of current help string */
- TBOOLEAN more_help;
- TBOOLEAN only; /* TRUE if only printing subtopics */
- int subtopics; /* 0 if no subtopics for this topic */
- int start; /* starting token of help string */
- char *help_ptr; /* name of help file */
- #if defined(SHELFIND)
- static char help_fname[256]=""; /* keep helpfilename across calls */
- #endif
- #if defined(MTOS) || defined(ATARI)
- char const *const ext[] = {NULL};
- #endif
-
- if ((help_ptr = getenv("GNUHELP")) == (char *) NULL)
- #ifndef SHELFIND
- /* if can't find environment variable then just use HELPFILE */
-
- /* patch by David J. Liu for getting GNUHELP from home directory */
- #if defined(__TURBOC__) && (defined(MSDOS) || defined(DOS386))
- help_ptr = HelpFile ;
- #else
- #if defined(MTOS) || defined(ATARI)
- {
- if ((help_ptr = findfile(HELPFILE,getenv("GNUPLOTPATH"),ext)) == NULL)
- help_ptr = findfile(HELPFILE,getenv("PATH"),ext);
- if (!help_ptr)
- help_ptr = HELPFILE;
- }
- #else
- help_ptr = HELPFILE;
- #endif /* MTOS || ATARI */
- #endif /* __TURBOC__ */
- /* end of patch - DJL */
-
- #else
- /* try whether we can find the helpfile via shell_find. If not, just
- use the default. (tnx Andreas) */
-
- if( !strchr( HELPFILE, ':' ) && !strchr( HELPFILE, '/' ) &&
- !strchr( HELPFILE, '\\' ) ) {
- if( strlen(help_fname)==0 ) {
- strcpy( help_fname, HELPFILE );
- if( shel_find( help_fname )==0 ) {
- strcpy( help_fname, HELPFILE );
- }
- }
- help_ptr=help_fname;
- } else {
- help_ptr=HELPFILE;
- }
- #endif /* SHELFIND */
-
- /* Since MSDOS DGROUP segment is being overflowed we can not allow such */
- /* huge static variables (1k each). Instead we dynamically allocate them */
- /* on the first call to this function... */
- if (helpbuf == NULL) {
- helpbuf = alloc((unsigned long)MAX_LINE_LEN, "help buffer");
- prompt = alloc((unsigned long)MAX_LINE_LEN, "help prompt");
- helpbuf[0] = prompt[0] = 0;
- }
- len = base = strlen(helpbuf);
-
- /* find the end of the help command */
- for (start = c_token; !(END_OF_COMMAND); c_token++);
- /* copy new help input into helpbuf */
- if (len > 0)
- helpbuf[len++] = ' '; /* add a space */
- capture(helpbuf + len, start, c_token - 1, MAX_LINE_LEN-len);
- squash_spaces(helpbuf + base); /* only bother with new stuff */
- lower_case(helpbuf + base); /* only bother with new stuff */
- len = strlen(helpbuf);
-
- /* now, a lone ? will print subtopics only */
- if (strcmp(helpbuf + (base ? base + 1 : 0), "?") == 0) {
- /* subtopics only */
- subtopics = 1;
- only = TRUE;
- helpbuf[base] = '\0'; /* cut off question mark */
- } else {
- /* normal help request */
- subtopics = 0;
- only = FALSE;
- }
-
- switch (help(helpbuf, help_ptr, &subtopics)) {
- case H_FOUND:{
- /* already printed the help info */
- /* subtopics now is true if there were any subtopics */
- screen_ok = FALSE;
-
- do {
- if (subtopics && !only) {
- /* prompt for subtopic with current help string */
- if (len > 0)
- (void) sprintf(prompt, "Subtopic of %s: ", helpbuf);
- else
- (void) strcpy(prompt, "Help topic: ");
- read_line(prompt);
- num_tokens = scanner(input_line);
- c_token = 0;
- more_help = !(END_OF_COMMAND);
- if (more_help)
- /* base for next level is all of current helpbuf */
- do_help();
- } else
- more_help = FALSE;
- } while (more_help);
-
- break;
- }
- case H_NOTFOUND:{
- printf("Sorry, no help for '%s'\n", helpbuf);
- break;
- }
- case H_ERROR:{
- perror(help_ptr);
- break;
- }
- default:{ /* defensive programming */
- int_error("Impossible case in switch", NO_CARET);
- /* NOTREACHED */
- }
- }
-
- helpbuf[base] = '\0'; /* cut it off where we started */
- }
- #endif /* _Windows */
-
- #ifdef AMIGA_AC_5
- char strg0[256];
- #endif
-
- static void do_system()
- {
- #ifdef AMIGA_AC_5
- char *parms[80];
- void getparms();
-
- getparms(input_line + 1, parms);
- if (fexecv(parms[0], parms) < 0)
- #else
- #if (defined(ATARI)&&defined(__GNUC__)) /* || (defined(MTOS)&&defined(__GNUC__)) */
- /* use preloaded shell, if available */
- short (*shell_p) (char *command);
- void *ssp;
-
- ssp = (void *) Super(NULL);
- shell_p = *(short (**) (char *)) 0x4f6;
- Super(ssp);
-
- /* this is a bit strange, but we have to have a single if */
- if ((shell_p ? (*shell_p) (input_line + 1) : system(input_line + 1)))
- #else
- #ifdef _Windows
- if (winsystem(input_line + 1))
- #else
- if (system(input_line + 1))
- #endif
- #endif
- #endif
- os_error("system() failed", NO_CARET);
- }
-
- #ifdef AMIGA_AC_5
-
- /******************************************************************************/
- /* */
- /* Parses the command string (for fexecv use) and converts the first token */
- /* to lower case */
- /* */
- /******************************************************************************/
-
- void
- getparms(command, parms)
- char *command;
- char **parms;
- {
- register int i = 0; /* A bunch of indices */
- register int j = 0;
- register int k = 0;
-
- while (*(command + j) != '\0') { /* Loop on string characters */
- parms[k++] = strg0 + i;
- while (*(command + j) == ' ')
- ++j;
- while (*(command + j) != ' ' && *(command + j) != '\0') {
- if (*(command + j) == '"') /* Get quoted string */
- for (*(strg0 + (i++)) = *(command + (j++));
- *(command + j) != '"';
- *(strg0 + (i++)) = *(command + (j++)));
- *(strg0 + (i++)) = *(command + (j++));
- }
- *(strg0 + (i++)) = '\0';/* NUL terminate every token */
- }
- parms[k] = '\0';
-
- for (k = strlen(strg0) - 1; k >= 0; --k) /* Convert to lower case */
- *(strg0 + k) >= 'A' && *(strg0 + k) <= 'Z' ? *(strg0 + k) |= 32 : *(strg0 + k);
- }
-
- #endif /* AMIGA_AC_5 */
-
- #ifdef READLINE
- char *
- rlgets(s, n, prompt)
- char *s;
- int n;
- char *prompt;
- {
- static char *line = (char *) NULL;
- static int leftover = -1; /* index of 1st char leftover from last call */
-
- if(leftover== -1) {
- /* If we already have a line, first free it */
- if (line != (char *) NULL)
- free(line);
-
- line = readline((interactive) ? prompt : "");
- leftover=0;
- /* If it's not an EOF */
- if (line && *line)
- add_history(line);
- }
- if(line) {
- strncpy(s, line+leftover, n);
- s[n-1]='\0';
- leftover+=strlen(s);
- if(line[leftover]=='\0')
- leftover = -1;
- return s;
- }
-
- return NULL;
- }
- #endif /* READLINE */
-
- #if defined(MSDOS) || defined(_Windows) || defined(DOS386)
-
-
-
- static void do_shell()
- {
- register char *comspec;
- if ((comspec = getenv("COMSPEC")) == (char *) NULL)
- comspec = "\\command.com";
- #ifdef _Windows
- if (WinExec(comspec, SW_SHOWNORMAL) <= 32)
- #else
- #ifdef DJGPP
- if (system(comspec) == -1)
- #else
- if (spawnl(P_WAIT, comspec, NULL) == -1)
- #endif
- #endif
- os_error("unable to spawn shell", NO_CARET);
- }
-
- #else /* MSDOS */
- /* plain old Unix */
-
- #ifdef AMIGA_SC_6_1
- static void do_shell()
- {
- register char *shell;
- if (!(shell = getenv("SHELL")))
- shell = SHELL;
-
- if (system(shell))
- os_error("system() failed", NO_CARET);
-
- (void) putc('\n', stderr);
- }
- #else /* AMIGA_SC_6_1 */
- #ifdef OS2
- static void do_shell()
- {
- register char *shell;
- if (!(shell = getenv("COMSPEC")))
- shell = SHELL;
-
- if (system(shell) == -1 )
- os_error("system() failed", NO_CARET);
-
- (void) putc('\n', stderr);
- }
- #else /* ! OS2 */
- #define EXEC "exec "
- static void do_shell()
- {
- static char exec[100] = EXEC;
- register char *shell;
- if (!(shell = getenv("SHELL")))
- shell = SHELL;
-
- if (system(strncpy(&exec[sizeof(EXEC) - 1], shell,
- sizeof(exec) - sizeof(EXEC) - 1)))
- os_error("system() failed", NO_CARET);
-
- (void) putc('\n', stderr);
- }
- #endif /* OS2 */
- #endif /* AMIGA_SC_6_1 */
- #endif /* MSDOS */
-
- /* read from stdin, everything except vms */
-
- #ifndef READLINE
- #if (defined(MSDOS) || defined(DOS386)) && !defined(_Windows) && !defined(__EMX__) && !defined(DJGPP)
-
- /* if interactive use console IO so CED will work */
-
- #define PUT_STRING(s) cputs(s)
- #define GET_STRING(s,l) ((interactive) ? cgets_emu(s,l) : fgets(s,l,stdin))
-
- #ifdef __TURBOC__
- /* cgets implemented using dos functions */
- /* Maurice Castro 22/5/91 */
- char *
- doscgets(s)
- char *s;
- {
- long datseg;
-
- /* protect and preserve segments - call dos to do the dirty work */
- datseg = _DS;
-
- _DX = FP_OFF(s);
- _DS = FP_SEG(s);
- _AH = 0x0A;
- geninterrupt(33);
- _DS = datseg;
-
- /* check for a carriage return and then clobber it with a null */
- if (s[s[1] + 2] == '\r')
- s[s[1] + 2] = 0;
-
- /* return the input string */
- return (&(s[2]));
- }
- #endif /* __TURBOC__ */
-
- #ifdef __ZTC__
- void cputs(char *s)
- {
- register int i = 0;
- while (s[i] != '\0') bdos(0x02, s[i++], NULL);
- }
- char *cgets(char *s)
- {
- bdosx(0x0A, s, NULL);
-
- if (s[s[1]+2] == '\r')
- s[s[1]+2] = 0;
-
- /* return the input string */
- return(&(s[2]));
- }
- #endif /* __ZTC__ */
-
- /* emulate a fgets like input function with DOS cgets */
- char *cgets_emu(str, len)
- char *str;
- int len;
- {
- static char buffer[128]="";
- static int leftover=0;
-
- if(buffer[leftover]=='\0') {
- buffer[0]=126;
- #ifdef __TURBOC__
- doscgets(buffer);
- #else
- cgets(buffer);
- #endif
- fputc('\n', stderr);
- if(buffer[2]==26)
- return NULL;
- leftover=2;
- }
- strncpy(str, buffer+leftover, len);
- str[len-1]='\0';
- leftover+=strlen(str);
- return str;
- }
- #else /* !plain DOS */
-
- #define PUT_STRING(s) fputs(s, stderr)
- #define GET_STRING(s,l) fgets(s, l, stdin)
-
- #endif
- #endif /* READLINE */
-
- static int read_line(prompt)
- char *prompt;
- {
- int start = 0;
- TBOOLEAN more = FALSE;
- int last = 0;
-
- #ifndef READLINE
- if (interactive)
- PUT_STRING(prompt);
- #endif /* READLINE */
- do {
- /* grab some input */
- #ifdef READLINE
- if (((interactive)
- ? rlgets(&(input_line[start]), input_line_len - start,
- ((more) ? "> " : prompt))
- : fgets(&(input_line[start]), input_line_len - start, stdin))
- == (char *) NULL) {
- #else
- if (GET_STRING(&(input_line[start]), input_line_len - start)
- == (char *) NULL) {
- #endif /* READLINE */
- /* end-of-file */
- if (interactive)
- (void) putc('\n', stderr);
- input_line[start] = '\0';
- inline_num++;
- if (start > 0) /* don't quit yet - process what we have */
- more = FALSE;
- else
- return(1); /* exit gnuplot */
- } else {
- /* normal line input */
- last = strlen(input_line) - 1;
- if(last >= 0)
- {
- if (input_line[last] == '\n') { /* remove any newline */
- input_line[last] = '\0';
- /* Watch out that we don't backup beyond 0 (1-1-1) */
- if (last > 0)
- --last;
- } else if (last + 2 >= input_line_len) {
- extend_input_line();
- start = last+1;
- more = TRUE;
- continue; /* read rest of line, don't print "> " */
- }
-
- if (input_line[last] == '\\') { /* line continuation */
- start = last;
- more = TRUE;
- } else
- more = FALSE;
- }
- else
- more = FALSE;
- }
- #ifndef READLINE
- if (more && interactive)
- PUT_STRING("> ");
- #endif
- } while (more);
- return(0);
- }
- #endif /* vms */
-
- #ifdef _Windows
- /* there is a system like call on MS Windows but it is a bit difficult to
- use, so we will invoke the command interpreter and use it to execute the
- commands */
- int winsystem(s)
- char *s;
- {
- LPSTR comspec;
- LPSTR execstr;
- LPSTR p;
-
- /* get COMSPEC environment variable */
- #ifdef WIN32
- char envbuf[81];
- GetEnvironmentVariable("COMSPEC", envbuf, 80);
- if (*envbuf == '\0')
- comspec = "\\command.com";
- else
- comspec = envbuf;
- #else
- p = GetDOSEnvironment();
- comspec = "\\command.com";
- while (*p) {
- if (!strncmp(p,"COMSPEC=",8)) {
- comspec=p+8;
- break;
- }
- p+=strlen(p)+1;
- }
- #endif
- /* if the command is blank we must use command.com */
- p = s;
- while ((*p == ' ') || (*p == '\n') || (*p == '\r'))
- p++;
- if (*p == '\0')
- {
- WinExec(comspec, SW_SHOWNORMAL);
- }
- else
- {
- /* attempt to run the windows/dos program via windows */
- if (WinExec(s, SW_SHOWNORMAL) <= 32)
- {
- /* attempt to run it as a dos program from command line */
- execstr = (char *) malloc(strlen(s) + strlen(comspec) + 6);
- strcpy(execstr, comspec);
- strcat(execstr, " /c ");
- strcat(execstr, s);
- WinExec(execstr, SW_SHOWNORMAL);
- free(execstr);
- }
- }
-
- /* regardless of the reality return OK - the consequences of */
- /* failure include shutting down Windows */
- return(0); /* success */
- }
- #endif
-
- #if 0 /* not used */
- static int
- get_time_data(line,maxcol,cols,types,x,y,z)
- char *line;
- int maxcol, *cols, *types;
- double *x, *y, *z;
- {
- register int m, n, linestat;
- double val[3];
- char *s;
- static struct tm tm;
-
- linestat = 1;
- m = n = 0;
- s = line;
- while ((linestat == 1) && (n<maxcol)) {
- while (isspace(*s)) s++;
- if (*s == '\0') {
- linestat = 0;
- break;
- }
- n++;
- if (n == cols[m]) {
- if ( types[m] == TIME ) {
- if ((s = (char *) gstrptime(s,timefmt,&tm)) != NULL ) {
- val[m] = (double) gtimegm(&tm);
- m++;
- } else
- linestat = 2;
- } else if (isdigit(*s) || *s=='-' || *s=='+' || *s=='.') {
- val[m] = atof(s);
- m++;
- }
- else
- linestat = 2; /* abort the line non-digit in req loc */
- }
- while ((!isspace(*s)) && (*s != '\0')) s++;
- }
- if ( linestat == 2 )
- return(0);
- if ( m > 0 )
- *x = val[0];
- if ( m > 1 )
- *y = val[1];
- if ( m > 2 )
- *z = val[2];
- return(m);
- }
- #endif /* not used */
-